//
//  LocationTool.swift
//  ANOA
//
//  Created by 邱仙凯 on 2022/4/1.
//  Copyright © 2025 aowang. All rights reserved.
//  定位服务工具

import UIKit

struct LocationInfo {
    var coor = CLLocationCoordinate2D(latitude: 39.908813, longitude: 116.397570)
    var address = ""
    var city = ""
}

final class LocationTool:NSObject {
    
    private override init(){}
    static let shared = LocationTool()
    private var locationMgr:CLLocationManager?
    private var baiduLocManager: BMKLocationManager?
    
    
    var showIng = 0
    var showTimer:Timer?
    // 控制不重复执行
    func startRepeatControl() {
        KSLog("控制不重复")
        if LocationTool.shared.showTimer.isNone {
            KSLog("开启计时")
            LocationTool.shared.showIng = 10 // 10秒间隔
            LocationTool.shared.showTimer = Timer.scheduledTimer(timeInterval: 1,
                                                                 target:self,selector:#selector(showTimerAction),
                                                                 userInfo:nil,repeats:true)
            LocationTool.shared.showTimer!.fire()
        }
        
    }
    
    @objc func showTimerAction() {
        
        LocationTool.shared.showIng -= 1
        KSLog(LocationTool.shared.showIng)
        
        if LocationTool.shared.showIng == 0 {
            LocationTool.shared.showTimer?.invalidate()
            LocationTool.shared.showTimer = nil
            KSLog("关闭计时")
            
            if isBaiduMapPlatform() {
                self.baiduLocManager?.stopUpdatingLocation()
                self.baiduLocManager?.delegate = nil
                self.baiduLocManager = nil
                KSLog("关闭定位")
            } else {
                if self.locationMgr.isSome {
                    self.locationMgr?.stopUpdatingLocation()
                    self.locationMgr?.delegate = nil
                    self.locationMgr = nil
                    KSLog("关闭定位")
                }
            }
        }
    }
    
    
    
    
    
    lazy var opS: [nameBtnAction] = {
        var opS = [nameBtnAction]()
        opS = [nameBtnAction(name: "取消", action: { _ in
            
            self.comAV.dismiss()
            
        }),nameBtnAction(name: "立即设置", action: { _ in
            
            self.comAV.dismiss()
            
            let url = URL(string: UIApplication.openSettingsURLString)!
            if UIApplication.shared.canOpenURL(url) {
                UIApplication.shared.open(url)
            }
            
        })]
        return opS
    }()
    lazy var comAV:ComAlertV = {
        let v = ComAlertV()
        return v
    }()
    // 设为属性，防止定位申请一闪而过
    private lazy var cllocationManger:CLLocationManager = {
        return CLLocationManager()
    }()
    
    
    
    // 新版取值
    private var locationInfo = LocationInfo()
    private var refreshClo:((LocationInfo)->())?
    
    private var isOnce = true
    private var times = 0
    
    // 先赋值原有的 再给定位后的，体验较好
    func getlocInfo(once: Bool = true, refreshClo: @escaping (LocationInfo)->()) -> LocationInfo {
        
        self.isOnce = once
        self.times = 0
        
        self.fetchLocation(clearOri: false)
        self.refreshClo = refreshClo
        
        var newL = locationInfo
        if !isBaiduMapPlatform() {
            newL.coor = changeGaode(coor: newL.coor)
        }
        return newL
    }
    func changeGaode(coor:CLLocationCoordinate2D) -> CLLocationCoordinate2D {
        return  KS_MapKits.shared.transformFromWGSToGCJ(wgsLoc: coor)
    }
    
    func getAddress() -> String {
        return self.locationInfo.address
    }
    
    func getCoor() -> CLLocationCoordinate2D {
        if isBaiduMapPlatform() {
            return locationInfo.coor
        } else {
            return changeGaode(coor: locationInfo.coor)
        }
    }
    
    
    
    
    
    
    // clearOri 清空现有的定位数据
    func fetchLocation(clearOri:Bool = true) {
        if clearOri {
            self.locationInfo.coor = CLLocationCoordinate2D(latitude: 39.908813, longitude: 116.397570)
            self.locationInfo.address = ""
            self.locationInfo.city = ""
        }
        if self.getPermission() {
            self.initLocationMgr()
        }
        
    }
    
    @discardableResult
    func getPermission() -> Bool {
        if self.getLocationPermissibillity() {
            if  AMapPrivacyUtility.shared.handlePrivacyAgreeStatus() {
                if isBaiduMapPlatform() {
                    bMapHelper.shared.initMap()
                } else {
                    GaoDeHelper.shared.initGaoDe()
                }
                return true
            } else {
                return false
            }
        }  else {
            return false
        }
    }
    
    
    
    func initLocationMgr() {
        
        if isBaiduMapPlatform() {
            if self.baiduLocManager.isNone {
                self.baiduLocManager = BMKLocationManager()
                self.baiduLocManager?.delegate = self
                self.baiduLocManager?.coordinateType = BMKLocationCoordinateType.BMK09LL
                //设定定位精度，默认为 kCLLocationAccuracyBest
                self.baiduLocManager?.desiredAccuracy = kCLLocationAccuracyBest
                //设定定位类型，默认为 CLActivityTypeAutomotiveNavigation
                self.baiduLocManager?.activityType = CLActivityType.automotiveNavigation
                //指定定位是否会被系统自动暂停，默认为NO
                self.baiduLocManager?.pausesLocationUpdatesAutomatically = false
                self.baiduLocManager?.allowsBackgroundLocationUpdates = false
                /**
                 指定单次定位超时时间,默认为10s，最小值是2s。注意单次定位请求前设置。
                 注意: 单次定位超时时间从确定了定位权限(非kCLAuthorizationStatusNotDetermined状态)
                 后开始计算。
                 */
                self.baiduLocManager?.locationTimeout = 10
            }
            
            self.baiduLocManager?.startUpdatingLocation()
            
        } else {
            // 系统定位
            
            if self.locationMgr.isNone {
                self.startRepeatControl()
                self.locationMgr = CLLocationManager()
                self.locationMgr?.delegate = self
                self.locationMgr?.desiredAccuracy = kCLLocationAccuracyHundredMeters
                self.locationMgr?.startUpdatingLocation()
                
            }
        }
        
    }
    
    
    
    // 获取定位状态
    func getLocationPermissibillity() -> Bool {
    
        if CLLocationManager.authorizationStatus() == .denied || CLLocationManager.authorizationStatus() == .notDetermined {
            
            // 1. 還沒有詢問過用戶以獲得權限
            if CLLocationManager.authorizationStatus() == .notDetermined {
                DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.5) {
                    KSLog("弹出申请系统定位")
                    self.cllocationManger.requestWhenInUseAuthorization()
                }
                
            }
            // 2. 用戶不同意
            else if CLLocationManager.authorizationStatus() == .denied {
                DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.5) {
                    if !self.comAV.isShow() {
                        self.comAV.add(title: "打开定位开关", message: "请确认定位服务是否开启,请进入系统设置>隐私>定位服务中打开开关,并允许本应用使用定位服务", operateS: self.opS)
                        self.comAV.present()
                    }
                }
                
                
            }
            
            return false
        } else {
            return true
        }
        
        
    }
    
    
    func geoAction(_ location:CLLocation) {
        
        var dealLocation = location
        if isBaiduMapPlatform() {
            let trans = BMKCoordTrans(location.coordinate, BMK_COORD_TYPE.COORDTYPE_BD09LL, BMK_COORD_TYPE.COORDTYPE_COMMON)
            dealLocation = CLLocation(latitude: trans.latitude, longitude: trans.longitude)
        }

        
        let geocoder = CLGeocoder()
        geocoder.reverseGeocodeLocation(dealLocation) { (placemarks, error) in
            if error.isSome {
               
            }
            
            if let placemark = placemarks?.last {
                
                let address = "\(placemark.administrativeArea.unwrap)\(placemark.locality.unwrap)\(placemark.subLocality.unwrap)\(placemark.name.unwrap)"
                
                var cityx = placemark.locality
                if cityx == "" {
                    cityx = placemark.administrativeArea
                }
                
                self.locationInfo.address = address
                self.locationInfo.city = cityx.unwrap
         
                if let clo = self.refreshClo {
                    
                    if self.isOnce && self.times > 0 {
                        if isBaiduMapPlatform() {
                            self.baiduLocManager?.stopUpdatingLocation()
                        } else {
                            self.locationMgr?.stopUpdatingLocation()
                        }
                        return
                    }
                    
                    self.times += 1
                    
                    var newL = self.locationInfo
                    if isBaiduMapPlatform() {
                        // 定位改用百度 sdk 了, 所以这里坐标无需再做转换
//                        newL.coor = CoordinateTransform.wgs84ToBD09(newL.coor)
                    } else {
                        newL.coor = self.changeGaode(coor: newL.coor)
                    }
                    clo(newL)
                }
                
                
                // 定位会连续校正几次，回调几次，所以设置首次回调后延迟关闭
                //                DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 10) {
                //                    if self.locationMgr.isSome {
                //                        KSLog("关闭定位")
                //                        self.locationMgr?.stopUpdatingLocation()
                //                        self.locationMgr?.delegate = nil
                //                        self.locationMgr = nil
                //                    }
                //
                //                }
                
            }
        }
    }
    
    
 
    
}

extension LocationTool: CLLocationManagerDelegate {
    // 系统定位回调
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    
        let currentLocation = locations.last!
        
        if locationInfo.coor.latitude != currentLocation.coordinate.latitude && locationInfo.coor.longitude != currentLocation.coordinate.longitude {
            self.locationInfo.coor = currentLocation.coordinate
            self.geoAction(currentLocation)
        }  
    }
}

extension LocationTool: BMKLocationManagerDelegate {
    func bmkLocationManager(_ manager: BMKLocationManager, didUpdate location: BMKLocation?, orError error: (any Error)?) {
        if let currentLocation = location?.location {
            
            if locationInfo.coor.latitude != currentLocation.coordinate.latitude && locationInfo.coor.longitude != currentLocation.coordinate.longitude {
                self.locationInfo.coor = currentLocation.coordinate
                self.geoAction(currentLocation)
            }
        }
    }
}
